﻿using System;
using System.Collections.Generic;
using System.Text;
using Autodesk.Revit.DB;
using YArchitech.Revit;
using YJKRGeometry;

namespace HYCoordinate
{
	public class SlopeTagMaker
	{
		public List<Element> ThislstElement
		{
			get
			{
				return this.m_lstElement;
			}
			private set
			{
				this.m_lstElement = value;
			}
		}

		public SlopDataInfo ThisSlopData
		{
			get
			{
				return this.m_ThisSlopData;
			}
			private set
			{
				this.m_ThisSlopData = value;
			}
		}

		public SlopeTagMaker(Document m_doc, TwoInputDataPakcer input, XYZ inputmidPoint = null)
		{
			this.m_doc = m_doc;
			this.driection = input.GetDriection();
			this.midPoint = Utiltiy.GetMidPoint(input.GetPoint(0), input.GetPoint(1));
			if (inputmidPoint != null)
			{
				this.midPoint = inputmidPoint;
			}
			this.sumLength = Utiltiy.FeetMMChange(StaticRescource.ArchValues[0], false);
			this.arcWidth = Utiltiy.FeetMMChange(StaticRescource.ArchValues[1], false);
			this.arcPoint = this.midPoint.Add(this.driection.Normalize().Multiply(Utiltiy.FeetMMChange(StaticRescource.ArchValues[2], false)));
			this.slopeValue = input.GetParameters(0)[UseParameterEnum.Slope];
			this.makeArchLines();
		}

		public void DrawTag()
		{
			Transaction transaction = new Transaction(this.m_doc, "makeTag");
			try
			{
				transaction.Start();
				this.drawArch();
				this.makeTag();
				transaction.Commit();
			}
			catch (Exception)
			{
				if (transaction.HasStarted())
				{
					transaction.RollBack();
				}
			}
		}

		private void makeArchLines()
		{
			this.lstLines = new List<Line>();
			XYZ xyz = new XYZ(-this.driection.Y, this.driection.X, this.driection.Z).Normalize();
			XYZ xyz2 = new XYZ(this.driection.Y, -this.driection.X, this.driection.Z).Normalize();
			Line item = Line.CreateBound(this.arcPoint, this.arcPoint.Add(Utiltiy.GetAVectorAnotherXY(this.driection).Multiply(this.sumLength)));
			Line item2 = Line.CreateBound(this.arcPoint, this.midPoint.Add(xyz2.Multiply(this.arcWidth / 2.0)));
			Line item3 = Line.CreateBound(this.arcPoint, this.midPoint.Add(xyz.Multiply(this.arcWidth / 2.0)));
			Line item4 = Line.CreateBound(this.midPoint.Add(xyz.Multiply(this.arcWidth / 2.0)), this.midPoint.Add(xyz2.Multiply(this.arcWidth / 2.0)));
			this.lstLines.Add(item);
			this.lstLines.Add(item2);
			this.lstLines.Add(item3);
			this.lstLines.Add(item4);
		}

		private void drawArch()
		{
			foreach (Line line in this.lstLines)
			{
				this.m_lstElement.Add(this.m_doc.Create.NewDetailCurve(this.m_doc.ActiveView, line));
			}
		}

		private void makeTag()
		{
			if (null == StaticRescource.GetTextStyleElementId(this.m_doc))
			{
				return;
			}
			TextNoteType textNoteType = this.m_doc.GetElement(StaticRescource.GetTextStyleElementId(this.m_doc)) as TextNoteType;
			if (textNoteType == null)
			{
				return;
			}
			string slopeString = StaticRescource.GetSlopeString(this.slopeValue);
			double num = textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble();
			SlopeTagMaker.GetLength(slopeString);
			double num2 = textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble();
			double num3 = textNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble();
			byte[] bytes = Encoding.Default.GetBytes(slopeString);
			double num4 = num2 * num3;
			if (num4 < 1.0)
			{
				num4 = 1.0;
			}
			double num5 = (double)bytes.Length * num4 / 1.7;
			Line line = this.lstLines[0];
			Line line2 = line.CreateSameOffset(1.1 * this.arcWidth / 2.0, StaticRescource.GetXYPlaneNorme(0)) as Line;
			Curve curve = line.CreateSameOffset(1.1 * this.arcWidth / 2.0, StaticRescource.GetXYPlaneNorme(1)) as Line;
			XYZ xyz = line2.GetEndPoint(0).Add(-line.GetEndPoint(0)).Normalize();
			XYZ xyz2 = curve.GetEndPoint(0).Add(-line.GetEndPoint(0)).Normalize();
			XYZ xyz3;
			double num6;
			if (-1.0 < this.driection.Y && 1.0 >= this.driection.Y && this.driection.X >= 0.0)
			{
				xyz3 = Utiltiy.GetLineMidPoint(line).Add(xyz.Multiply(1.1 * num5 / 2.0));
				num6 = this.driection.AngleTo(new XYZ(1.0, 0.0, 0.0));
				if (0.0 > this.driection.Y)
				{
					num6 = -num6;
				}
			}
			else
			{
				num6 = this.driection.AngleTo(new XYZ(-1.0, 0.0, 0.0));
				xyz3 = Utiltiy.GetLineMidPoint(line).Add(xyz2.Multiply(1.1 * num5 / 2.0));
				if (0.0 <= this.driection.Y)
				{
					num6 = -num6;
				}
			}
			double num7 = textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).AsDouble() * 100.0 * (double)this.m_doc.ActiveView.Scale / 100.0;
			double num8 = textNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).AsDouble();
			double num9 = num7 * num8;
			double lineWidth = (double)(slopeString.Length * 2) * num9 / (double)this.m_doc.ActiveView.Scale;
            TextNote textNode = this.m_doc.GetTextNode(this.m_doc.ActiveView, xyz3, XYZ.BasisX, XYZ.BasisY, lineWidth, (TextAlignFlags)1024, slopeString, textNoteType);
			textNode.GetParameter(BuiltInParameter.TEXT_ALIGN_HORZ).Set(128);
			BoundingBoxXYZ boundingBoxXYZ = textNode.get_BoundingBox(this.m_doc.ActiveView);
			if (boundingBoxXYZ == null)
			{
				boundingBoxXYZ = new BoundingBoxXYZ();
				boundingBoxXYZ.Max = RevitElementExtension.GetTextNoteCoord(textNode) + RevitElementExtension.GetTextNoteWidth(textNode) * textNode.BaseDirection;
				if (!Geometry.IsEqual(textNode.Height, 0.0))
				{
					boundingBoxXYZ.Min = RevitElementExtension.GetTextNoteCoord(textNode) - textNode.Height * textNode.UpDirection;
				}
				else
				{
					boundingBoxXYZ.Min = RevitElementExtension.GetTextNoteCoord(textNode) - num7 * textNode.UpDirection;
				}
			}
			ElementTransformUtils.RotateElement(this.m_doc, textNode.Id, Utiltiy.GetMidAixZPlane(boundingBoxXYZ), num6);
			ElementTransformUtils.MoveElement(this.m_doc, textNode.Id, xyz3.Add(-Utiltiy.GetMidPoint(boundingBoxXYZ.Max, boundingBoxXYZ.Min)));
			this.ThislstElement.Add(textNode);
			this.ThisSlopData = new SlopDataInfo(this.midPoint, this.driection, this.slopeValue);
		}

		private static int GetLength(string str)
		{
			if (str.Length == 0)
			{
				return 0;
			}
			Encoding encoding = new ASCIIEncoding();
			int num = 0;
			byte[] bytes = encoding.GetBytes(str);
			for (int i = 0; i < bytes.Length; i++)
			{
				if (bytes[i] == 63)
				{
					num += 2;
				}
				else
				{
					num++;
				}
			}
			return num;
		}

		private Document m_doc;

		private XYZ driection;

		private XYZ arcPoint;

		private XYZ midPoint;

		private double sumLength;

		private double arcWidth;

		private double slopeValue;

		private List<Line> lstLines;

		private List<Element> m_lstElement = new List<Element>();

		private SlopDataInfo m_ThisSlopData;
	}
}
